#include <stdlib.h>
#include <stdio.h>
typedef unsigned int u32;
typedef unsigned char u8;
//typedef unsigned long __uint64_t;
//typedef long unsigned int uint64_t;
/*
 * 常量宏定义
 */

#define	YH_ROCE_GID_SIZE_M				16
#define YH_ROCE_PAGE_SHIFT_M            12
#define YH_ROCE_PAGE_SIZE_M             4096 

#define YH_ROCE_CQC_SIZE_M              32
#define YH_ROCE_CQE_SIZE_M              32
#define YH_ROCE_MAX_CQ_NUM_M        	64
#define YH_ROCE_MIN_CQE_NUM_M           64
#define YH_ROCE_CQ_MIN_SIZE_M           2048

#define YH_ROCE_MR_DAT_SIZE_M           1024

#define YH_ROCE_QPC_SIZE_M              128 
#define YH_ROCE_SQE_SIZE_M              128
#define YH_ROCE_RQE_SIZE_M              32
#define YH_ROCE_MIN_WQE_NUM_M           64
#define YH_ROCE_SQ_MIN_SIZE_M           8192 
#define YH_ROCE_RQ_MIN_SIZE_M           2048 
#define DSP_MEM_ROCE_MR_ADDR_V          ((uint64_t)0x55a605062d90 )
#define DSP_MEM_ROCE_SQ_ADDR_V          ((uint64_t)0x7f22d5da5000 )

/*
 * 地址变量
 */
const unsigned int DSP_MEM_BASE_ADDR_V;
const unsigned int DSP_MEM_ROCE_ADDR_V;
const unsigned int DSP_MEM_DEVI_ADDR_V = 0xf200000;

unsigned int DSP_MEM_ROCE_QP_ADDR_V;
//unsigned int DSP_MEM_ROCE_SQ_ADDR_V;
unsigned int DSP_MEM_ROCE_RQ_ADDR_V;
unsigned int DSP_MEM_ROCE_CQ_ADDR_V;
//unsigned int DSP_MEM_ROCE_MR_ADDR_V;

unsigned int DSP_MEM_DEVI_DB_ADDR_V;
unsigned int DSP_MEM_DEVI_MB_ADDR_V = DSP_MEM_DEVI_ADDR_V+0x200;
//long unsigned int DSP_MEM_ROCE_MR_ADDR_V = 0x55a605062d90;
//long unsigned int DSP_MEM_ROCE_SQ_ADDR_V = 0x7f22d5da5000;
unsigned int DSP_MEM_ROCE_MTR_QP_ADDR_V;
unsigned int DSP_MEM_ROCE_MTR_CQ_ADDR_V;
unsigned int DSP_MEM_ROCE_MTR_MR_ADDR_V;
#if 0
DSP_MEM_BASE_ADDR_V = 0;
DSP_MEM_ROCE_ADDR_V = 0;
DSP_MEM_DEVI_ADDR_V = 0;

DSP_MEM_ROCE_QP_ADDR_V = (DSP_MEM_ROCE_ADDR_V+16384);
DSP_MEM_ROCE_SQ_ADDR_V = (DSP_MEM_ROCE_ADDR_V+16384);
DSP_MEM_ROCE_RQ_ADDR_V = (DSP_MEM_ROCE_ADDR_V+24576);
DSP_MEM_ROCE_CQ_ADDR_V = (DSP_MEM_ROCE_ADDR_V+30720);
DSP_MEM_ROCE_MR_ADDR_V = (DSP_MEM_ROCE_ADDR_V+36864);

DSP_MEM_ROCE_MTR_QP_ADDR_V = (DSP_MEM_ROCE_ADDR_V+40960);
DSP_MEM_ROCE_MTR_CQ_ADDR_V = (DSP_MEM_ROCE_ADDR_V+45056);
DSP_MEM_ROCE_MTR_MR_ADDR_V = (DSP_MEM_ROCE_ADDR_V+49152);

// DSP_MEM_DEVI_DB_ADDR_V = DSP_MEM_DEVI_ADDR_V;
// DSP_MEM_DEVI_MB_ADDR_V = DSP_MEM_DEVI_ADDR_V + 0xf200200;

/*
 * 以下为写内存
 * 需要转换为汇编指令
 */

/*
 * QP的MTR表赋值
 */
(DSP_MEM_ROCE_MTR_QP_ADDR_V) = (DSP_MEM_ROCE_ADDR_V+16384);
(DSP_MEM_ROCE_MTR_QP_ADDR_V+8) = (DSP_MEM_ROCE_ADDR_V+20480);
(DSP_MEM_ROCE_MTR_QP_ADDR_V+16) = (DSP_MEM_ROCE_ADDR_V+24576);
(DSP_MEM_ROCE_MTR_QP_ADDR_V+24) = (DSP_MEM_ROCE_ADDR_V+28672);

/*
 * CQ的MTR表赋值
 */
(DSP_MEM_ROCE_MTR_CQ_ADDR_V) = (DSP_MEM_ROCE_ADDR_V+30720);

/*
 * MR的MTR表赋值
 */
(DSP_MEM_ROCE_MTR_MR_ADDR_V) = (DSP_MEM_ROCE_ADDR_V+36864);
#endif

/**
 * @struct dsp_sw_roce_mtr
 * @brief 软件维护，MR MTR、QP MTR、CQ MTR空间相关信息
 */
struct dsp_sw_roce_mtr{

    u32 mtr_startaddr_l                                  ; // MTR's start addr 
    u32 mtr_startaddr_h                                ;
    u32 mtr_size                                       ; // MTR地址空间大小
    u32 mtr_npages                                     ; // MR pages number

};


/**
 * @struct dsp_sw_roce_wq
 * @brief 软件维护,可对应SQ或RQ（在此只使用SQ）
 */
struct dsp_sw_roce_wq{

    u32 wq_startaddr_l                                  ; //WQ起始地址的低32为
    u32 wq_startaddr_h                                  ; //WQ起始地址的高32为
    u32 wq_size                                       ; // WQ地址空间大小
    u32 wq_npages                                     ; // WQ pages number
    u32	wq_depth                                      ; // WQE num max
    u32	wq_head                                       ; // PI
	u32	wq_tail                                       ; // CI
    u32	wqe_size                                      ;	// one WQE size
    struct dsp_sw_roce_mtr	mr_mtr                    ; //
    //u32	wqe_cnt                                       ; // now WQE num  硬件并未使用该字段
    // lock 尚未确定如何实现

};



/**
 * @struct dsp_sw_roce_qp
 * @brief 软件维护，每个QP都有一个该结构体,QP空间相关信息
 */
struct dsp_sw_roce_qp{

    u32 qp_startaddr_l                                ; // QP起始地址的低32位
    u32 qp_startaddr_h                                ; // QP起始地址的高32为
    u32 qp_size                                       ; // QP地址空间大小
    u32 qp_npages                                     ; // QP pages number
    u32 qp_key                                        ;
    struct dsp_sw_roce_wq qp_sq                       ;
    struct dsp_sw_roce_wq qp_rq                       ;
    struct dsp_sw_roce_mtr	qp_mtr                    ; // 存储QP地址表项
    u32 qp_qpn                                        ; 
    u32	qp_cqn                                        ;
	u8 qp_state                                       ;
    u8 qp_valid                                       ;

};



struct dsp_sw_remote_addr {

    u32 byte_4_addr_l                           ;// 为远端地址低32bit
    u32 byte_4_addr_h                           ;// 为远端地址高32bit

};//每个RC QP都对应一个远端的地址

/**
 * @struct ddsp_udp_connect_data
 * @brief  通信双端交互的建链信息
 */
struct dsp_udp_connect_data {

    u32 byte_4_sgeaddr32                                 ;// 0-31 sgeaddr32
    u32 byte_8_sgeaddr32                                 ;// 32-63 sgeaddr32
    u32 byte_12_rkey                                     ;// 64-95 rkey
    u32 byte_16_qpn                                      ;// 96-127 qpn
    u32 byte_20_lid16                                    ;// 128-143 lid16   144-159 rev
    u8  gid[16]                                          ;// 160-287 gid
    u32 psn24                                            ;// 288-311 psn   312-319 rev
    u32 rlength                                          ;// 320-351 remote memory size
};//参考荀鹏老师np_write_rdma代码中建链数据结构
//PSN可以默认为0 
//如果对端只有一个 可以提前写好GID 
//LID可能也是直接写的0 需要确认一下
//这里没有传输 远程内存大小  是因为默认两端申请的MR空间大小一样大
//在此预留各种发送写请求可能需要发送的信息
/**
 * @struct dsp_sw_roce_mr
 * @brief 软件维护，MR空间相关信息
 */
struct dsp_sw_roce_mr {

	u32 mr_startaddr_l                                  ; // MR's start addr 
    u32 mr_startaddr_h                                  ;
	u32 mr_size                                       ; // MR数据地址空间大小, 应用输入  Address range of MR 
	u32	mr_key                                        ; // Key of MR
	u32	mr_pdn                                        ; // PD num of MR 
	u32	mr_access                                     ; // Access permission of MR 
	u32	mr_npages                                     ; // MR pages number
	struct dsp_sw_roce_mtr	mr_mtr                    ; // 存储MR地址表项mr mtr表占3个页
    u32 mr_nowaddr                                    ; // MR's now addr for transport
    u8	mr_enabled                                    ; // MR's active status
};


/**
 * @struct dsp_sw_roce_cq
 * @brief 软件维护，每个CQ都有一个该结构体,CQ空间相关信息
 */
struct dsp_sw_roce_cq{

    u32 cq_startaddr_l                                  ; // CQ's start addr 
    u32 cq_startaddr_h                                  ;
    u32 cq_size                                       ; // CQ地址空间大小
    u32 cq_npages                                     ; // CQ pages number
    struct dsp_sw_roce_mtr	cq_mtr                    ; // 存储CQ地址表项
    u32	cq_depth                                      ; // CQE num max
	u32	cq_tail                                       ; // CI 硬件说写啥就写啥 PI在硬件处维护 只告知软件CI信息
    u32 cq_cqn                                        ; 
    u8 cq_valid                                       ;

};

